# -*- coding: utf-8 -*-

import sys, os
try:
        import pygtk
        pygtk.require("2.0")
except:
        pass
try:
        import gtk
        import gtk.glade
	import pango
	import gobject
except:
        sys.exit(1)
from thread import start_new_thread
from simpledcpp.gui.widgets.list import NickListTree
from simpledcpp.core.base import DCPPPart, DCPPEvent
import time
from simpledcpp.gui.HumanReadableSize import HRS
from threading import Lock
from simpledcpp.gui.base import gtk_lock_required

class ChatWindow(DCPPPart):
	def __init__(self, parent):
		DCPPPart.__init__(self, parent)
		self.Events.Subscribe("ON_HUB_CONNECT_START", self._startConnect)
		self.Events.Subscribe("ON_HUB_CONNECT_OK", self._connected)
		self.Events.Subscribe("ON_HUB_CONNECT_FAILED", self._failed)
		self.Events.Subscribe("ON_HUB_DISCONNECTED", self._failed)
		self.Events.Subscribe("ON_HUB_MESSAGE",self._message)
		self._buf = gtk.TextBuffer()
		self._txtwidget = gtk.TextView(self._buf)
		self._txtwidget.set_border_width(2)
		self._txtwidget.set_editable(False)
		self._txtwidget.set_wrap_mode(gtk.WRAP_WORD)
		self._txtwidget.set_size_request(500,400)
#		self._txtwidget.request_size(500,500)

		self._txtwidget.set_cursor_visible(False)

		self._txtwidget.show()
		self._widget = gtk.ScrolledWindow()
                self._widget.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		self._widget.add(self._txtwidget)
		self._widget.show()
		self._widget.set_size_request(400, 200)

	@gtk_lock_required
	def _startConnect(self, Event):
		if Event.userdata[0] == self.parent.name:
			self.add(_("Starting connect to") + " <%s>.\n"%Event.userdata[0])

	@gtk_lock_required
	def _connected(self, Event):
		if Event.userdata[0] == self.parent.name:
			self.add(_("Connected") + ".\n")
	@gtk_lock_required
	def _failed(self, Event):
		if Event.userdata[0] == self.parent.name:
			self.add(_("Connect failed because") + ": %s\n"%Event.userdata[1])
			self.parent._showReconnect()

	@gtk_lock_required
	def _message(self, Event):
		if Event.userdata[0] == self.parent.name:
			self.parse_insert(Event.userdata[1])


        def parse_insert(self, mg):

                try:
                        if mg.startswith('<'):
                                mg.index(">")
                                newmg = mg.split('>',1)
                                nickname = newmg[0].replace("<","")
                                message = newmg[1]
                                tag = self._buf.create_tag()
                                tag.set_property('foreground','blue')
                                tag.set_property('foreground-set',True)
#                               tag.set_property('underline', pango.UNDERLINE_SINGLE)
#                               tag.set_property('underline-set', True)
                                tag.connect("event", self._tagevent, "private:%s"%nickname)
                                self.add("<")
                                self.add(nickname, tag)
                                self.add("> ")
				mg = message
#                                self.add(message + '\n')
#                                return
                except:
                        pass
#                       print sys.exc_info()



                try:
                        index = mg.index("://")
                        for i in mg.split(' '):
                                try:
                                        i.index("://")
                                        tag = self._buf.create_tag()
                                        tag.set_property("foreground", "blue")
                                        tag.set_property("foreground-set", True)
                                        tag.set_property("underline", pango.UNDERLINE_SINGLE)
                                        tag.set_property("underline-set", True)
					tag.connect("event", self._tagevent, i)
                                        self.add("%s"%i, tag)
					self.add(" ")
                                except:
                                        self.add("%s "%i)
                        self.add("\n")
                        return
                except:
                        pass

                try:
                        index = mg.index("magnet:")
                        for i in mg.split(' '):
                                try:
                                        i.index("magnet:")
                                        tag = self._buf.create_tag()
                                        tag.set_property("foreground", "blue")
                                        tag.set_property("foreground-set", True)
                                        tag.set_property("underline", pango.UNDERLINE_SINGLE)
                                        tag.set_property("underline-set", True)
					tag.connect("event", self._tagevent, i)
                                        self.add("%s"%i, tag)
					self.add(" ")
                                except:
                                        self.add("%s "%i)
                        self.add("\n")
                        return
                except:
                        pass

                self.add("%s\n"%(mg))

        def _tagevent(self,texttag = None, widget = None, event = None, iter = None, param = None):
                if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1:
                        if param.split(':')[0] == 'magnet':
                                self.Event(DCPPEvent("OPEN_MAGNET", (param,)))
			elif param.split(":")[0] == 'private':
				self.Event(DCPPEvent("OPEN_PRIVATE",(param.split(":")[1], self.parent.name)))

				

	def add(self, message, Tag = None):
                iter = self._buf.get_iter_at_offset(self._buf.get_char_count())
                if Tag == None:
                        self._buf.insert(iter, message)
                else:
#			Tag.connect("event", self._tagevent, message)
                        self._buf.insert_with_tags(iter, message, Tag)
                iter = self._buf.get_iter_at_offset(self._buf.get_char_count())
                self._txtwidget.scroll_to_iter(iter,0, True)

	def Close(self, *args, **kwargs):
                self.Events.Unsubscribe("ON_HUB_CONNECT_START", self._startConnect)
                self.Events.Unsubscribe("ON_HUB_CONNECT_OK", self._connected)
                self.Events.Unsubscribe("ON_HUB_CONNECT_FAILED", self._failed)
                self.Events.Unsubscribe("ON_HUB_DISCONNECTED", self._failed)
                self.Events.Unsubscribe("ON_HUB_MESSAGE",self._message)

class NickList(DCPPPart):
	def __init__(self, parent):
		DCPPPart.__init__(self, parent)
		self._nickiters = {}
		self.Events.Subscribe("ON_USER_CONNECT", self._adduser)
		self.Events.Subscribe("ON_USER_DISCONNECT", self._deluser)
		self.Events.Subscribe("MESSAGE_TO", self._checkUser)
                menu_items = (
                 ( "/_" + _("Browse files"),     "filelist", self.get_filelist, 0, None ),
		 ( "/_" + _("Send message"), "sendmessage", self.private_message, 0 , None),
                 )
		self._nicklist = NickListTree([_('User'),_('Information'),_('Speed'),_('E-mail'),_('Sharesize'),"INVISIBLE"],
						menu_items,str,str,str,str,str,gobject.TYPE_INT64)
		self._nicklist.treestore.set_sort_func(4, self._sort_func, None)
		self._widget = gtk.ScrolledWindow()
		self._widget.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		self._widget.add(self._nicklist.widget)
		self._widget.set_border_width(5)
		self._widget.show()
		self._widget.set_size_request(400, 200)
		self.HRS = HRS()

	def _sort_func(self, treemodel, iter1, iter2, data = None):
		first = self._nicklist.treestore.get_value(iter1, 5)
		second = self._nicklist.treestore.get_value(iter2, 5)
		if first > second:
			return 1
		elif first < second:
			return -1
		else:
			return 0

	@gtk_lock_required
	def _checkUser(self, Event):
		_h, _n, _t = Event.userdata
#		print _h, self.parent.name
		if self.parent.name == _h:
			try:
				if not self._nickiters.has_key(_n):
					self.Event(DCPPEvent("USER_OFFLINE", (_h, _n)))
					##print "USER_OFFLINE"
			except:
				print sys.exc_info()
	@gtk_lock_required
	def _adduser(self, Event):
		_hub, _nick, _interest, _speed, _email, _sharesize = Event.userdata
		_hsharesize = self.HRS.byteToHuman(int(_sharesize))
		if self.parent.name == _hub:
			if not self._nickiters.has_key(_nick):
				self._nickiters[_nick] = self._nicklist.append((_nick, _interest, _speed, _email, _hsharesize,int(_sharesize)))
				self.Event(DCPPEvent("USER_ONLINE", (_hub, _nick)))

#		self.parent.activate()
	@gtk_lock_required
	def _deluser(self, Event):
		_hub, _nick = Event.userdata
		if self.parent.name == _hub:
			try:
				self._nicklist.remove(self._nickiters[_nick])
				self._nickiters.pop(_nick)
			except:
				pass
		self.parent.activate()

	def get_filelist(self, *args, **kwargs):
		self.Event(DCPPEvent("GET_FILELIST", (self.parent.name, self._nicklist.selected_rows[0])))

	def private_message(self, *args, **kwargs):
		self.Event(DCPPEvent("OPEN_PRIVATE", (self._nicklist.selected_rows[0], self.parent.name)))

	def Close(self, *args, **kwargs):
                self.Events.Unsubscribe("ON_USER_CONNECT", self._adduser)
                self.Events.Unsubscribe("ON_USER_DISCONNECT", self._deluser)
                self.Events.Unsubscribe("MESSAGE_TO", self._checkUser)

class ServerPage(DCPPPart):
	def activate(self, *args, **kwargs):
		self.Event(DCPPEvent("LSB",(_("Users online") +": %s"%len(self._nicklist._nickiters),)))

	# Activate out of 6 seconds, while all nicknames added.
	def timeout(self, *args, **kwargs):
		time.sleep(6)
		self.activate()

	def __init__(self,parent, address, forceName = None):
		DCPPPart.__init__(self, parent)
		self.type = "Server"
		if forceName == None:
			self.name = address
		else:
			self.name = forceName
		self._chatentry = gtk.Entry()
		self._chatentry.connect('key-press-event', self._onkey)
		self._chatwindow = ChatWindow(self)
		VBOX = gtk.VBox()
		VBOX.pack_start(self._chatwindow._widget)
		VBOX.pack_start(self._chatentry, False, False)
		self._reconnectButton = gtk.Button('Label',gtk.STOCK_REFRESH)
		self._reconnectButton.connect('clicked', self.reconnectTo)
#		self._reconnectButton.set_visible(False)
		VBOX.pack_start(self._reconnectButton, False, False) 
		self._chatwindow._widget.show()
		self._chatentry.show()
		VBOX.show()	
		HPaned = gtk.HPaned()
		HPaned.pack1(VBOX)
		self._nicklist = NickList(self)
		HPaned.pack2(self._nicklist._widget)
		self._widget = HPaned
		self._widget.show()
		start_new_thread(self.timeout, ())
	def Close(self):
		self._nicklist.Close()
		self._chatwindow.Close()
		self.parent._dcpp.DisconnectFrom(self.name)

	def _onkey(self, widget,  Event, *args, **kwargs):
		if Event.keyval == 65293 and self._chatentry.get_text() != "":
			text = self._chatentry.get_text()
			self.Event(DCPPEvent("PRIVATE_MESSAGE", (self.name, text)))
			self._chatentry.set_text("")

	def _showReconnect(self, *args, **kwargs):
		self._reconnectButton.show()

	def reconnectTo(self, *args, **kwargs):
		self._hideReconnect()
		self.parent._reconnectTo(self.name)

	def _hideReconnect(self, *args, **kwargs):
		self._reconnectButton.hide()
